using System;

namespace SmartLib.Core
{
	/// <summary>
	/// Base Class for Creation of Singleton Objects <para/>
	/// (The inheritor must define a private constructor)
	/// </summary>
	/// <typeparam name="T">The type that should be exposed</typeparam>
	public abstract class SingletonBase<T> : ObservableBase where T : new()
	{
		private static T _instance;
		private static readonly object _syncObj = new object();

		/// <summary>
		/// Creates the instance.
		/// </summary>
		/// <returns>The new instance for <see cref="SingletonBase&lt;T&gt;"/></returns>
		protected static T CreateInstance()
		{
			var instance = Activator.CreateInstance<T>();
			return instance;
		}

		/// <summary>
		/// Gets the instance.
		/// </summary>
		/// <value>The instance.</value>
		public static T Instance
		{
			get
			{
				// init if null (or equals to default value)
				if(Equals(_instance, default(T)))
				{
					// lock thread
					lock (_syncObj)
					{
						// dbl chk
						if (Equals(_instance, default(T)))
						{
							_instance = CreateInstance();
						}
					}
				}
				return _instance;
			}
		}
	}
}